package com.xhj.mybatis.scripting.xmltags.ognl.other;

import com.xhj.mybatis.reflection.Reflector;
import ognl.MemberAccess;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Member;
import java.util.Map;

/**
 * PublicOgnlMemberAccess
 *
 * @author XJks
 * @description PublicOgnlMemberAccess，与源码不同，该类构造方法为公有，以便测试类使用。
 */
public class PublicOgnlMemberAccess implements MemberAccess {

    private final boolean canControlMemberAccessible;

    public PublicOgnlMemberAccess() {
        this.canControlMemberAccessible = Reflector.canControlMemberAccessible();
    }

    @Override
    public Object setup(Map context, Object target, Member member, String propertyName) {
        // 声明一个变量用于保存成员的原始访问状态
        Object result = null;
        // 判断是否允许控制成员可访问性
        if (isAccessible(context, target, member, propertyName)) {
            // 将 member 强制转换为 AccessibleObject（Field、Method 都是 AccessibleObject 的子类）
            AccessibleObject accessible = (AccessibleObject) member;
            // 如果当前成员不可访问
            if (!accessible.isAccessible()) {
                // 标记原本不可访问
                result = Boolean.FALSE;
                // 设置成员为可访问（绕过 Java 的访问控制检查）
                accessible.setAccessible(true);
            }
        }
        // 返回原始访问状态（用于后续恢复）
        return result;
    }

    @Override
    public void restore(Map context, Object target, Member member, String propertyName, Object state) {
        // todo:源码说明:由于 accessible 标志的修改不是线程安全的，这里不做恢复操作。
    }

    @Override
    public boolean isAccessible(Map context, Object target, Member member, String propertyName) {
        // 直接返回 canControlMemberAccessible 字段
        return canControlMemberAccessible;
    }

}
